import React, {ReactNode, useCallback, useEffect, useRef, useState} from 'react';
import {Input, InputProps, ITouchEvent, Textarea, View} from '@tarojs/components';
import {
  Form,
  Radio,
  RadioGroup,
  Checkbox,
  CheckboxGroup,
  Slider,
  Rate,
  Stepper,
  Uploader,
  DatetimePicker,
  Button,
  FormItem,
  Switch,
  Icon, Picker,
} from '@antmjs/vantui';
import Utils from "@/utils/common";
import DialogUtils from "@/utils/dialog_utils";
import BottomButton from "@/pages/components/bottom_button";
import './dynamic_form.less';
import {IFormInstanceAPI} from "@antmjs/vantui/types/form";
import config from "../../../config";


// 表单配置类型
export interface OptionConfig {
  label: string;
  text?: string;
  id?: string;
  value: string | number;
  disabled?: boolean;
}

export interface FormConfig {
  type: string;
  name: string;
  label: string;
  placeholder?: string;
  layout?: 'vertical' | 'horizontal'
  options?: Array<OptionConfig>;
  required?: boolean;
  rules?: any[];
  maxlength?: number;
  maxHeight?: number;
  minHeight?: number;
  renderReactNode?: () => ReactNode
  showWordLimit?: boolean;
  disabled?: boolean;
  password?: boolean
  min?: number;
  max?: number;
  step?: number;
  count?: number;
  isHideItem?: boolean | undefined;
  inputBgColor?: string;
  padding?: string;
  inputType?: keyof InputProps.Type;
  timeType?: "datetime" | "date" | "year-month" | "time" | undefined;

  [key: string]: any;
}

export interface DynamicFormProps {
  /**
   * Form configuration array
   */
  formConfigs: FormConfig[];

  /**
   * Initial form values
   */
  initialValues?: Record<string, any>;

  /**
   * Callback when form is submitted with valid values
   */
  onSubmit?: (values: Record<string, any>) => void;

  /**
   * Callback when form submission fails with errors
   */
  onError?: (errors: any) => void;
  handleSubmit?: () => void;
  onChange?: (name: string, result: any) => any

  /**
   * Text for submit button
   * @default "提交"
   */
  submitText?: string;

  /**
   * Whether to show Dialog alerts for form errors and success
   * @default false
   */
  showDialogs?: boolean;
  inputBgColor?: string;
  form?: IFormInstanceAPI


}

const DynamicForm: React.FC<DynamicFormProps> = ({
                                                   formConfigs,
                                                   initialValues = {},
                                                   onSubmit,
                                                   onError,
                                                   submitText = '提交',
                                                   inputBgColor,
                                                   showDialogs = false,
                                                 }) => {
  const form = useRef(Form.useForm());
  const [, forceUpdate] = useState({});

  const handleFormChange = (key: string, value: any) => {
    form.current.setFieldsValue(key, value);
  };

  const handleFormChange2 = useCallback((e, name) => {
    handleFormChange(name, e.detail);
    forceUpdate({});
  }, []);


  const getFieldValue = useCallback((name: string) => {
    return form.current.getFieldValue(name)
  }, []);


  const valueFormatUpload = (event, formName, instance) => {
    Utils.showLoading('上传中...');
    const {file} = event.detail;
    let fileList = instance.getFieldValue(formName) || [];
    fileList = fileList.concat(file);

    // 异步更新
    return new Promise((resolve) => {
      setTimeout(() => {
        Utils.clear();
        resolve(fileList);
      }, 3000);
    });
  };

  const deleteFile = (event, formName) => {
    Utils.showLoading('删除中...');
    const {index, fileList} = event.detail;
    fileList.splice(index, 1);
    handleFormChange(formName, fileList)
    forceUpdate({});
    Utils.clear();
  };

  const handleSubmit = () => {
    form.current.validateFields((errorMessage, fieldValues) => {
      if (errorMessage && errorMessage.length) {
        if (showDialogs) {
          DialogUtils.showAlert('提示', `errorMessage: ${JSON.stringify(errorMessage)}`, true, () => {
          })
        }
        if (onError) {
          onError(errorMessage);
        }
        return;
      }
      if (showDialogs) {
        DialogUtils.showAlert('提示', `errorMessage: ${JSON.stringify(fieldValues)}`, true, () => {
        })
      }

      if (onSubmit) {
        onSubmit(fieldValues);
      }
    });
  };


  // 渲染动态表单项
  const renderFormItem = (config: FormConfig) => {
    const layout = config.layout || 'horizontal';
    const style = config.layout === "vertical" ? {
      '--form-controll-margin-left': '0PX',
      width: '100%',
      padding: '0'
    } : {width: '100%', padding: '0'};

    switch (config.type) {
      case 'input':
        return (
          <FormItem
            name={config.name}
            label={config.label}
            rules={config.rules}
            required={config.required}
            trigger='onInput'
            validateTrigger='onBlur'
            layout={layout}
            style={style}
            borderBottom={layout === 'horizontal'}
            valueFormat={(e) => e.detail.value}
          >
            <Input
              password={config.password}
              disabled={config.disabled}
              maxlength={config.maxlength}
              type={config.inputType}
              placeholder={config.placeholder}
              style={{
                width: '100%',
                backgroundColor: config.inputBgColor,
                padding: config.padding ? config.padding : '0 5PX'
              }}
            />
          </FormItem>
        );

      case 'textarea':
        return (
          <FormItem
            name={config.name}
            label={config.label}
            rules={config.rules}
            required={config.required}
            trigger='onInput'
            validateTrigger='onBlur'
            layout={layout}
            style={style}
            borderBottom={layout === 'horizontal'}
            valueFormat={(e) => e.detail.value}
          >
            <Textarea
              placeholder={config.placeholder}
              maxlength={config.maxlength}
              trigger='onInput'
              validateTrigger='onBlur'
              valueFormat={(e) => e.detail.value}
              style={{
                width: '100%',
                maxHeight: config.maxHeight ? config.maxHeight : '80PX',
                padding: '10px',
                minHeight: config.minHeight ? config.minHeight : '40PX',
                height: config.minHeight ? config.minHeight : '40PX',
                lineHeight: 'normal',
                backgroundColor: config.inputBgColor
              }}
            />
          </FormItem>
        );

      case 'radio':
        return (
          <FormItem name={config.name} label={config.label} layout={layout} style={style}>
            <RadioGroup
              onChange={(e) => handleFormChange2(e, config.name)}
              direction='horizontal'
              style={{display: 'flex', flexWrap: 'wrap', gap: '10px'}}
            >
              {config.options ? config.options.map((option) => (
                <Radio
                  key={option.value}
                  name={String(option.value)}
                  shape='square'
                  disabled={option.disabled}
                >
                  {option.label}
                </Radio>
              )) : <View>无</View>}
            </RadioGroup>
          </FormItem>
        );

      case 'checkbox':
        return (
          <FormItem name={config.name} label={config.label} layout={layout} style={style}>
            <CheckboxGroup
              onChange={(e) => handleFormChange2(e, config.name)}
              direction='horizontal'
              style={{display: 'flex', flexWrap: 'wrap', gap: '10px'}}
            >
              {config.options ? config.options.map((option) => (
                <Checkbox key={option.value} name={String(option.value)} shape='square'>
                  {option.label}
                </Checkbox>
              )) : <View>无</View>}
            </CheckboxGroup>
          </FormItem>
        );

      case 'switch':
        return (
          <FormItem name={config.name} label={config.label} layout={layout} style={style}>
            <Switch
              onChange={(e) => handleFormChange2(e, config.name)}
              checked={getFieldValue(config.name)}
            />
          </FormItem>
        );

      case 'slider':
        return (
          <FormItem name={config.name} label={config.label} layout={layout} style={style}>
            <Slider
              activeColor='#07c160'
              min={config.min}
              max={config.max}
              step={config.step}
              style={{width: '90%', margin: '10px'}}
            />
          </FormItem>
        );

      case 'rate':
        return (
          <FormItem name={config.name} label={config.label} layout={layout} style={style}>
            <Rate count={config.count} onChange={(e) => handleFormChange2(e, config.name)}/>
          </FormItem>
        );

      case 'stepper':
        return (
          <FormItem name={config.name} label={config.label} layout={layout} style={style}>
            <Stepper
              min={config.min}
              max={config.max}
              step={config.step}
              onChange={(e) => handleFormChange2(e, config.name)}
            />
          </FormItem>
        );
      case 'render':
        return (
          config.renderReactNode ? config.renderReactNode() : null
        );
      case 'uploader':
        return (
          <FormItem
            name={config.name}
            label={config.label}
            valueKey='fileList'
            valueFormat={valueFormatUpload}
            trigger='onAfterRead'
            layout={layout}
            style={style}
            validateTrigger='onAfterRead'
            rules={{
              rule: (values, call) => {
                if (!values || !Array.isArray(values)) {
                  return call('');
                }

                values.forEach((item, index) => {
                  if (item && item.size > 0.1 * 1024 * 1024) {
                    return call(`图片(${index + 1})大小不得大于 0.1M`);
                  }
                });
                call('');
              },
            }}
          >
            <Uploader
              fileList={getFieldValue(config.name) || []}
              maxCount={config.maxCount || 5}
              onDelete={(e) => {
                deleteFile(e, config.name);
              }}
            />
          </FormItem>
        );

      case 'datePicker':
        return (
          <FormItem
            name={config.name}
            label={config.label}
            valueFormat={(e) => e.detail.value}
            valueKey='value'
            style={style}
            trigger='onInput'
            layout={layout}
            renderRight={<Icon name='arrow'/>}
          >
            <DatetimePicker
              value={getFieldValue(config.name)}
              mode='content'
              type={config.timeType}
            />
          </FormItem>
        );
      case 'picker':
        return (
          <FormItem
            valueFormat={(e) => e.detail}
            trigger='onInput'
            label={config.label}
            name={config.name}
            valueKey='value'
            required={config.required}
            controllFlexEnd
          >
            <Picker
              idKey='value'
              mode='content'
              showToolbar
              title={config.placeholder}
              columns={config.options}
              showArrowRight
            />
          </FormItem>
        );

      default:
        return null;
    }
  };
  return (
    <View className='dynamic-form-container'>
      <View style={{flex: 1}}>
        <Form form={form.current} onFinish={handleSubmit} initialValues={initialValues}>
          {formConfigs.map((config, index) => (
            <View key={`${config.name}-${index}`}>
              {renderFormItem(config)}
            </View>
          ))}
        </Form>
      </View>
      <BottomButton submitText={submitText} onSubmit={handleSubmit}/>
    </View>
  );
};

export default DynamicForm;
